/**
 * 
 */
package org.red5.webapps.admin.listeners;

import java.util.ArrayList;
import java.util.Iterator;

import org.red5.server.api.IConnection;
import org.red5.server.api.IScope;
import org.red5.server.api.IServer;
import org.red5.server.api.Red5;
import org.red5.server.api.ScopeUtils;
import org.red5.server.api.listeners.IConnectionListener;
import org.red5.server.api.statistics.IScopeStatistics;
import org.red5.server.net.remoting.RemotingClient;
import org.red5.webapps.admin.Application;
import org.red5.webapps.admin.utils.Utils;

/**
 * @author Krishna
 *
 */

public class ServerConnectionListener implements IConnectionListener {

	private IServer server;
	private Application admin;
	private RemotingClient informer;
	private String amfGateway;
	private String service;
	private String serverid;
	
	/* (non-Javadoc)
	 * @Constructor
	 */
	public ServerConnectionListener(IServer server,Application admin){
		this.server = server;
		this.admin = admin;
		this.serverid = admin.getServerid();
		this.amfGateway = admin.getAmfGateway();
		this.service = admin.getService();
		this.init();
	}
	
	
	/* (non-Javadoc)
	 * @Indicates Red5 startup
	 */
	@SuppressWarnings("unchecked")
	public void init()
	{
		ArrayList applications = new ArrayList();
		Iterator<String> scopes = admin.getApplicationNames();
		
		while (scopes.hasNext()){
			String scopename = scopes.next();
			String realname = scopename.substring(1, scopename.length());
		    if(realname.length()>0) applications.add(realname);
		}
		
		try{
		this.informer = new RemotingClient(this.amfGateway);	
		informer.invokeMethod(service+".initStats", new Object[]{serverid,applications});
		}catch(Exception e){
			// NO-OP
		}
	}
	
	
	
	/* (non-Javadoc)
	 * @see org.red5.server.api.listeners.IConnectionListener#notifyConnected(org.red5.server.api.IConnection)
	 */
	@Override
	public void notifyConnected(IConnection arg0) {
		System.out.println("Connected");
	}

	
	
	/* (non-Javadoc)
	 * @see org.red5.server.api.listeners.IConnectionListener#notifyDisconnected(org.red5.server.api.IConnection)
	 */
	@SuppressWarnings({ "unchecked" })
	@Override
	public void notifyDisconnected(IConnection arg0) {
		try{
		ArrayList info = getStats(arg0);
		postStats(info);
		}catch(Exception e){
			// TO DO
		}
		System.out.println("Disconnected");
	}
	
	
	
	/* (non-Javadoc)
	 * @Post server stats
	 */
	@SuppressWarnings("unchecked")
	public void postStats(ArrayList info)
	{
		try{
		Object[] args = new Object[]{serverid,info};
		informer.invokeMethod(service+".postStats",args);
		}catch(Exception e){
			// NO-OP
		}
	}
	
	
	/* (non-Javadoc)
	 * @Read stats from server into info list
	 */
	@SuppressWarnings("unchecked")
	public ArrayList getStats(IConnection arg0) throws Exception
	{
		ArrayList snapshot = new ArrayList();
		
		IScope appScope = ScopeUtils.findApplication(arg0.getScope());
		IScopeStatistics stats = appScope.getStatistics();
		
		/* Application Data */
		
		String applicationname = stats.getName();
		snapshot.add(applicationname);
		
		int totalConnections = stats.getTotalConnections();
		snapshot.add(totalConnections);
		
		int activeConnections = stats.getActiveConnections();
		snapshot.add(activeConnections);
		
		int totalScopes = stats.getTotalSubscopes();
		snapshot.add(totalScopes);
		
		int activeSubscopes = stats.getActiveSubscopes();
		snapshot.add(activeSubscopes);
		
		int totalClients = stats.getTotalClients();
		snapshot.add(totalClients);
		
		int activeClients = stats.getActiveClients();
		snapshot.add(activeClients);
		
		
		/* Connection Data */
		
		String clientSentBytes = Utils.formatBytes(arg0.getWrittenBytes());
		snapshot.add(clientSentBytes);
		
		String clientRecievedBytes = Utils.formatBytes(arg0.getReadBytes());
		snapshot.add(clientRecievedBytes);
		
		long clientSentMessages = arg0.getWrittenMessages();
		snapshot.add(clientSentMessages);
		
		long clientRecievedMessages = arg0.getReadMessages();
		snapshot.add(clientRecievedMessages);
		
		String connectionType = arg0.getType();
		snapshot.add(connectionType);
		
		String connectionIP = arg0.getRemoteAddress();
		snapshot.add(connectionIP);
		
		long creationTime = arg0.getClient().getCreationTime();
		snapshot.add(creationTime);
		
		String host = arg0.getHost();
		snapshot.add(host);
		
		return snapshot;
	}

}
